/**
 * gedulemgr.h is part of Gedule.
 *
 * Gedule is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Gedule is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Gedule.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef GeduleMGR_H
#define GeduleMGR_H

#include <string>
#include <vector>
#include "definitions.h"
#include "model/model.h"

#define GET_GEDULE_MGR() ( GeduleMgr::Instance() )

// Typedefs.
// ---------

/* Callbacks vector */
typedef std::vector< std::pair< tCallback, void * > > tCallbacks;

/* Callbacks available */
typedef enum
{
    // Always last.
    N_CALLBACKS
} tCallbackId;

/* Run modes */
typedef enum
{
    CONSOLE_MODE = 0,
    GUI_MODE,

    // Always last.
    N_RUN_MODES
} RunMode;

/* Loggers */
typedef enum
{
    LOG_LOGGER,

    // Always last.
    N_LOGGERS
} Loggers;

class GeduleMgr
{
public:

    ~GeduleMgr();

    static GeduleMgr & Instance();

    bool Init();
    short Run( int argc, char * argv [], RunMode a_mode = CONSOLE_MODE );
    bool Stop();

    void Subscribe( tCallback a_callback, void * a_object, tCallbackId a_callbackId );

    const Model & GetModel() const;
    Model & GetModel();

    bool OpenModel( const std::string & a_file );
    bool SaveModel( const std::string & a_file );

private:

    // Fields
    // ------

    static GeduleMgr m_instance;

    static const std::string LICENSE;
    static const std::string VERSION;

    Model       m_model;
    tCallbacks  m_callbacks [ N_CALLBACKS ];

    // Methods
    // -------

    bool InitLoggers();

    void Notify( tCallbackId a_callbackId, void * a_param );

    short RunConsoleMode();
    short RunGUIMode( int argc, char * argv [] );

    // Protect default constructor.
    GeduleMgr();

    // Protect default copy constructor.
    GeduleMgr( const GeduleMgr & a_other );

    // Protect default operator =.
    GeduleMgr & operator = ( const GeduleMgr & a_other );

};

#endif // GeduleMGR_H
